home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The X-Philes (2nd Revision)
/
The X-Philes Number 1 (1995).iso
/
xphiles
/
hp48_1
/
grob2eps
< prev
next >
Wrap
Internet Message Format
|
1995-03-31
|
7KB
From comp.sys.handhelds Sun Jan 27 14:05:11 1991
Path: mentor.cc.purdue.edu!noose.ecn.purdue.edu!news.cs.indiana.edu!know!sdd.hp.com!hp-pcd!hpcvra.cv.hp.com!rnews!hpcvbbs!akcs.rkb
From: akcs.rkb@hpcvbbs.UUCP (Robert Brunner)
Newsgroups: comp.sys.handhelds
Subject: Re: How does one print out a GROB from a PC?
Keywords: GROB, PC printing
Message-ID: <27a26d9b:1803.2comp.sys.handhelds;1@hpcvbbs.UUCP>
Date: 27 Jan 91 06:40:07 GMT
References: <1991Jan24.182436.20395@rick.cs.ubc.ca> <7360058@hpfcso.HP.COM>
Lines: 255
I've been meaning to write a program to print out GROBs
for some time. Reading the previous posts motivated
me to finally do it. The program runs on PC-compatibles
under MS-DOS. Some directions for use can be found in the
comments for the program. I'm only posting the source code
(written in Turbo C) here, but I will also post the executable
on hpcvbbs in user.programs. I hope this helps you out.
By the way, this program was written and tested in one Saturday
afternoon, so it probably includes some bugs (at no extra charge :-))
I'd be interested if others add more options; please get back
to me if you do.
Robert Brunner
brunner@uirvld.csl.uiuc.edu
/*
/
** grob2eps.c version 1.0
** Robert Brunner
** 1-26-91
**
** Translate a GROB to a file which can be copied to an Epson
** printer. The GROB is sent from the HP-48 to the PC using
** ASCII mode. The program is then run with the command:
**
** C>grob2eps grob_file print_file
**
** and the results can be printed with the MS-DOS copy command:
**
** C>copy print_file /b prn
**
** If either filename is omitted, stdin or stdout are used.
** Therefore, another way to execute the command is:
**
** C>grob2eps grob_file >prn
**
** Bugs:
** 1) Specifying PRN for the print_file sends garbage to the printer
** 2) The program is slow as molasses
**
** This program was developed for MS-DOS with Turbo C 2.0, although
** no machine-specific are used, so it may be usable on other
** systems.
*/
#include <stdio.h>
#define GROBTYP "GROB"
#define ESC 27
main(argc,argv)
int argc;
char *argv[];
{
FILE *fp_in, *fp_out;
char ftyp[5], *grobmap;
unsigned char *bmap;
int realwidth,width,realheight,height,i;
long grobsize;
/*
** Open files from the command line, or use stdin and stdout
*/
if (argc>=2) {
if ((fp_in=fopen(argv[1],"r"))==NULL) {
fprintf(stderr,"Can't open grob file\n");
exit(1);
}
} else fp_in=stdin;
if (argc>=3) {
if ((fp_out=fopen(argv[2],"wb"))==NULL) {
fprintf(stderr,"Can't open print file\n");
exit(2);
}
} else fp_out=stdout;
/*
** Find the first occurence of GROB and print out this.
** This gets the file pointer past the %%HP junk.
*/
while (!feof(fp_in)) {
fscanf(fp_in,"%5s",ftyp);
if (strcmp(GROBTYP,ftyp)==0)
break;
}
if (feof(fp_in)) {
fprintf(stderr,"Unexpected eof\n");
exit(3);
}
/*
** Get the GROB size and the actual grob data
** Notice that the width is rounded up to the next multiple
** of eight, since this is how they are transmitted.
** The real width is saved for printing because the
** lines are completed with 1's
*/
fscanf(fp_in,"%d %d ",&realwidth,&realheight);
if (realwidth%8==0)
width=realwidth;
else width=((realwidth/8)+1)*8;
if (realheight%8==0)
height=realheight;
else height=((realheight/8)+1)*8;
grobmap=(char *)malloc(sizeof(char)*(width/4)*height+1);
if (grobmap==NULL) {
fprintf(stderr,"GROB too big. Exiting\n");
exit(4);
}
fgets(grobmap,(width/4)*height+1,fp_in);
/*
** Create memory space for a bitmap and clear that memory
** to zero
*/
bmap=(unsigned char *)malloc(sizeof(char)*width*(height/8));
if (bmap==NULL) {
fprintf(stderr,"GROB too big. Exiting\n");
exit(4);
}
for(i=0;i<width*(height/8);i++)
bmap[i]=0;
/*
** Translate the grob string to a bitmap where each byte
** represents 8 rows from 1 column. This makes printing
** upright images easier.
*/
generate_bmap(grobmap,width,bmap);
/*
** Print out the bitmap
*/
print_out(bmap,width,realwidth,height,fp_out);
/*
** Clean up and exit
*/
free(grobmap);
free(bmap);
fclose(fp_in);
fclose(fp_out);
exit(0);
}
int generate_bmap(grobmap,width,bmap)
char *grobmap;
int width;
unsigned char *bmap;
{
int i,j,bmaprow,bmapcol,bitrow;
char ch,*chptr;
unsigned char val,*bmap_indx,maptable0[16][8],maptable1[16][8],
maptable2[16][8],maptable3[16][8];
/*
** Initialize maptable#[hexnum][rownum] This array gives the
** table which tells which columns (0-3) are 1 or 0 for each hex digit
** and each row in the bitmap.
** Note that the order of the bits is reversed since the HP-48 sends
** the grobs this way, ie. bit 0 is the leftmost bit and 3
** the rightmost bit
*/
for(i=1;i<16;i++)
for(j=0;j<8;j++) {
maptable0[i][j]=((i & 0x1) > 0) << j;
maptable1[i][j]=((i & 0x2) > 0) << j;
maptable2[i][j]=((i & 0x4) > 0) << j;
maptable3[i][j]=((i & 0x8) > 0) << j;
}
/*
** Scan the string, setting the appropriate bits in bmap.
** Note that the MS bit of bmap is the top row.
*/
bmaprow=0;
bitrow=7;
bmapcol=0;
chptr=grobmap;
for(i=0;i<strlen(grobmap); i++,bmapcol+=4,chptr++) {
/*
** Calculate the value represented by the hex character
*/
ch=*chptr;
if ((ch>='0') && (ch<='9'))
val=ch-'0';
else {
ch=toupper(ch);
if ((ch>='A') && (ch<='F'))
val=ch-'A'+10;
else val=0;
}
/*
** Increment the current bit or column at the end of each row
*/
if (bmapcol>=width) {
bmapcol-=width;
bitrow--;
}
if (bitrow<0) {
bitrow=7;
bmaprow++;
}
/*
** Skip a bit if there is a zero
*/
if (val==0)
continue;
/*
** bitwise-or each pixel column with the appropriate value
*/
bmap_indx=bmap+bmapcol+width*bmaprow;
*bmap_indx++ |= maptable0[val][bitrow];
*bmap_indx++ |= maptable1[val][bitrow];
*bmap_indx++ |= maptable2[val][bitrow];
*bmap_indx |= maptable3[val][bitrow];
}
}
int print_out(bmap,width,realwidth,height,fp_out)
unsigned char *bmap;
int width,realwidth,height;
FILE *fp_out;
{
/*
** Print out the bitmap. This routine uses 8-bit single
** density mode for epson printers. On a 9-pin printer
** the output is 60(H)x72(V) dpi. or 60(H)x60(V) dpi on
** a 24-pin printer. A normal size GROB will be pretty
** small, but the calculator can produce larger ones
** which will have better resolution
*/
int i,j;
/*
** Set the line spacing
*/
fprintf(fp_out,"%c%c%c",ESC,'3',24);
for(j=0;j<(height/8);j++) {
/*
** Print out one line of points
*/
fprintf(fp_out,"%c%c%c%c",ESC,'K',realwidth%256,realwidth/256);
for(i=0;i<realwidth;i++)
fputc(*(bmap+j*width+i),fp_out);
/*
** End of line - CR,LF
*/
fprintf(fp_out,"%c%c",13,10);
}
/*
** Restore the printer line spacing to 1/6 inch.
*/
fprintf(fp_out,"%c%c",ESC,'2');
}